-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement adding uniqueness constraints to columns #53
Conversation
d6828cb
to
db2d9d1
Compare
208b47b
to
06ae0e4
Compare
I've one question here, when will the constraint start being enforced? If I understand correctly, it would only be after the call to complete. Ideally, we offer the guarantee that each version of the schema fully respects it. Meaning that accessing through the new version enforces the unique constraint while accessing the old one doesn't. If I'm not mistaken, it almost feels like we need to create a new column and copy all the data (optionally applying an up function), then enforce the constraint in the new column, but not in the old one. Does this make sense? |
Another though, I go back and forth with doing this as its own op or having it as part of the alter column operation. I start to see that alter column may be better, but we can decide on this later. |
f23568f
to
c712013
Compare
75bbe73
to
9d50a22
Compare
9d50a22
to
e01568a
Compare
Create a new table and then add a unique constraint on a pair of columns in a separate migration.
e01568a
to
5d64ac4
Compare
Uniqueness is enforced after start, when the We have a test that ensures that inserts to both the old and new schema that violate the constraint will fail: The only thing that |
Yes, I was thinking similarly. A single 'alter table' operation might be the best approach. |
We talked about this offline, and the outcome was:
|
…ions (#118) When `pg-roll` makes a schema change, the contract with the user is that it will leave the old version of schema unchanged. When the operation to add a `UNIQUE` constraint was implemented (#53), this contract was not respected. The operation adds a unique index to the existing column, changing the behaviour for users of the old schema. This PR changes the operation so that it follows a similar pattern to other operations that were implemented later: * On `Start`: * Duplicate the column. * Add a `UNIQUE` index concurrently * Create `up` and `down` triggers to copy values between the old and new columns. * Backfill values from the old column into the new using `up` SQL * On `Complete` * Create a unique constraint on the new column using the unique index. * Drop the old column * Rename the column to its old name. * Remove `up` and `down` triggers. Writing correct `up` SQL for the operation is a little more difficult than for other operations (eg set `NOT NULL`) as it is up to the user to ensure uniqueness of values. The example migration in this PR appends a random suffix to each value.
Add support for adding uniqueness constraints to columns. Such a migration looks like this:
This migration adds a unique constraint spanning the
username
andproduct
columns in thereviews
table.Start
a unique index is created concurrently.Rollback
the unique index is removed.Complete
a unique constraint is added to the column using the index.Creating a unique constraint directly requires a full table exclusive lock. By first creating a unique index concurrently and then adding a constraint using the index the need for the lock is avoided.